package com.rc.saas.tenant.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtil {
    private static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    /** 时间戳格式：yyyyMMddHHmmss **/
    public final static String TIMESTAMP_FORMAT = "yyyyMMddHHmmss";

    /** 完整的时间戳格式，精确到毫秒：yyyyMMddHHmmS **/
    public final static String TIMESTAMP_FULL_FORMAT = "yyyyMMddHHmmS";

    /** 短时间戳格式，yyMMddHHmmss **/
    public final static String TIMESTAMP_SHORT_FORMAT = "yyMMddHHmmss";

    /** 日期格式：yyyy-MM **/
    public final static String DATE_MONTH_FORMAT = "yyyy-MM";

    /** 日期格式：yyyy-MM-dd **/
    public final static String DATE_FORMAT = "yyyy-MM-dd";

    /** 日期格式：yyyy-MM-dd HH:mm:ss **/
    public final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    /** 日期格式：yyyy/MM/dd HH:mm:ss **/
    public final static String DATETIME_FORMAT = "yyyy/MM/dd HH:mm:ss";

    /** 日期格式：yyyyMMdd **/
    public final static String DATE_FORMAT_YYYYMMDD = "yyyyMMdd";

    /** 日期格式：yyyy-MM-dd HH:mm **/
    public final static String DATE_TIME_FORMAT_MINUTE = "yyyy-MM-dd HH:mm";

    /**
     * Date类型转为yyyy-MM-dd HH:mm:ss类型String
     */
    public static String formatDateTime(Date date) {
        return format(date, dateTimeFormatter);
    }

    /**
     * yyyy-MM-dd HH:mm:ss类型String转为DateTime
     */
    public static Date parseDateTime(String dateString) throws ParseException {
        DateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sf.parse(dateString);

    }
    /**
     * 获取时间戳，格式为：yyyyMMddHHmmss
     */
    public static String getTimestamp() {
        return format(new Date(), TIMESTAMP_FORMAT);
    }

    /**
     * 获取时间戳，格式为：yyMMddHHmmss
     */
    public static String getShortTimestamp() {
        return format(new Date(), TIMESTAMP_SHORT_FORMAT);
    }

    /**
     * 获取完整的时间戳，精确到毫秒，格式为：yyyyMMddHHmmS
     */
    public static String getFullTimestamp() {
        return format(new Date(), TIMESTAMP_FULL_FORMAT);
    }

    /**
     * 获取日期，格式:yyyy-MM-dd
     *
     * @return
     */
    public static String getDate() {
        return format(new Date(), DATE_FORMAT);
    }

    /**
     * 获取日期时间，格式：yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getDateTime() {
        return format(new Date(), DATE_TIME_FORMAT);
    }

    /**
     * 将日期格式化为yyyy-MM-dd
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return format(date, DATE_FORMAT);
    }

    /**
     * 将时间格式化为，格式：yyyy-MM-dd HH:mm
     *
     * @return
     */
    public static String formatDateTimeMinute(Date dateTime) {
        return format(dateTime, DATE_TIME_FORMAT_MINUTE);
    }

    /**
     * 日期格式化
     *
     * @param date
     * @param fmt
     * @return
     */
    public static String format(Date date, String fmt) {
        if (date == null)
            return null;
        SimpleDateFormat f = new SimpleDateFormat(fmt);
        return f.format(date);
    }

    public static long getCurrentDateLong() {
        return System.currentTimeMillis() / 1000;
    }

    /**
     * 字符串转换成日期,格式yyyy-MM-dd HH:mm:ss
     * @param str
     * @return date
     */
    public static Date strToDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat(DATE_TIME_FORMAT);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 字符串转换成日期
     * @param str formatString
     * @return date
     */
    public static Date strToDate(String str,String formatString) {
        SimpleDateFormat format = new SimpleDateFormat(formatString);
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 时间戳转换成日期,格式yyyyMMddHHmmss
     * @param str
     * @return date
     */
    public static Date timestrampToDate(String timestramp) {
        SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_FORMAT);
        Date date = null;
        try {
            date = format.parse(timestramp);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 时间戳转换成日期,格式yyMMddHHmmss
     * @param str
     * @return date
     */
    public static Date shortTimestrampToDate(String timestramp) {
        SimpleDateFormat format = new SimpleDateFormat(TIMESTAMP_SHORT_FORMAT);
        Date date = null;
        try {
            date = format.parse(timestramp);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 将日期格式化为：yyMMddHHmmss
     *
     * @param date
     * @return
     */
    public static String dateToShortTimestamp(Date date) {
        return format(date, TIMESTAMP_SHORT_FORMAT);
    }

    /**
     * 将日期格式化为yyyy-MM-dd
     *
     * @param time 秒数
     * @return
     */
    public static String formatDate(long time) {
        return format(new Date(time*1000), DATE_FORMAT);
    }

    /**
     * 获取昨天的日期
     * @return
     */
    public static String getYesterday(){
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DAY_OF_MONTH, -1);
        return formatDate(cal.getTime());
    }

    /**
     * 获取星期几，0:星期日 1：星期一 2:星期二 ...
     * @return
     */
    public static int getWeek(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.DAY_OF_WEEK) - 1;
    }

    /**
     * 获取小时
     * @return
     */
    public static int getHour(Date date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 在原来的日期基础上增加/减少n天，并返回增加/减少后的日期
     * @param date 原来的日期
     * @param days 天数，正数为增加，负数为减少
     * @return
     */
    public static Date addDays(Date date, int days){
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, days);
        return cal.getTime();
    }

    /**
     * 在原来的日期基础上增加/减少n天，并返回增加/减少后的日期
     * @param dateStr 原来的日期,格式yyyy-MM-dd
     * @param days 天数，正数为增加，负数为减少
     * @return
     */
    public static String addDays(String dateStr, int days){
        SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, days);
        return format(cal.getTime(), DATE_FORMAT);
    }


    /**
     * CP56Time2a格式的日期
     * CP56Time2a格式，7个字节，{毫秒(两个字节, 低位在前)，分，时，日，月，年（年—2000）}
     */
    public static byte[] getCP56Time2a(){
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int milliSecond = cal.get(Calendar.SECOND)*1000 + cal.get(Calendar.MILLISECOND);

        byte[] b = new byte[7];
        b[0] = (byte)(milliSecond);
        b[1] = (byte)(milliSecond >> 8);
        b[2] = (byte)minute;
        b[3] = (byte)hour;
        b[4] = (byte)day;
        b[5] = (byte)month;
        b[6] = (byte)(year - 2000);
        return b;
    }

    /**
     * CP56Time2a格式的日期
     * @param date 日期毫秒数
     */
    public static byte[] getCP56Time2a(long date){
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date(date));
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int day = cal.get(Calendar.DAY_OF_MONTH);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int milliSecond = cal.get(Calendar.SECOND)*1000 + cal.get(Calendar.MILLISECOND);

        byte[] b = new byte[7];
        b[0] = (byte)(milliSecond);
        b[1] = (byte)(milliSecond >> 8);
        b[2] = (byte)minute;
        b[3] = (byte)hour;
        b[4] = (byte)day;
        b[5] = (byte)month;
        b[6] = (byte)(year - 2000);
        return b;
    }

    /**
     * CP56Time2a格式的日期
     * @param date 格式:yyyy-MM-dd HH:mm:ss
     */
    public static byte[] getCP56Time2a(String dateStr){
        Date date = DateUtil.strToDate(dateStr);
        return getCP56Time2a(date.getTime());
    }

    /**
     * 计算两个日期相差的天数
     * @param startDateStr
     * @param endDateStr
     * @return
     * @throws ParseException
     */
    public static int getDaysDiff(String startDateStr,String endDateStr){
        int diff = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date startDate = sdf.parse(startDateStr);
            Date endDate = sdf.parse(endDateStr);
            diff = (int)((endDate.getTime()-startDate.getTime())/(1000*3600*24));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return diff;
    }

    /**
     * 检查日期格式是否合法
     * @param dateStr 日期, 格式yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static boolean checkFormat(String dateStr){
        try {
            dateStr = dateStr.replace(" ", "").replace("-", "").replace(":", "");
            //int year = Integer.valueOf(dateStr.substring(0, 4));
            int month = Integer.valueOf(dateStr.substring(4, 6));
            int day = Integer.valueOf(dateStr.substring(6, 8));
            int hour = Integer.valueOf(dateStr.substring(8, 10));
            int minute = Integer.valueOf(dateStr.substring(10, 12));
            int seconds = Integer.valueOf(dateStr.substring(12));
            if((month < 1 || month > 12)
                    || (day < 1 || day > 31)
                    || (hour > 23)
                    || (minute > 59)
                    || (seconds > 59)){
                return false;
            }
            return true;
        }catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public static String format(Date date, DateTimeFormatter formatter) {
        if (date == null) {
            return null;
        }
        DateTime dateTime = new DateTime(date);
        return dateTime.toString(formatter);
    }

    private static DateTime parse(String date, DateTimeFormatter formatter) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        DateTime dateTime = formatter.parseDateTime(date);
        return dateTime;
    }

    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static String getPastDate(int past,Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
        Date today = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String result = sdf.format(today);
        return result;
    }

    /**
     * 获取上个月的第一天起始时间
     * @return
     */
    public static Date getLastMonthStart(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH,-1);
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.set(Calendar.HOUR_OF_DAY,0);
        calendar.set(Calendar.MINUTE,0);
        calendar.set(Calendar.SECOND,0);
        calendar.set(Calendar.MILLISECOND,0);
        return calendar.getTime();
    }

    /**
     * 获取上个月的最后一天结束时间
     * @return
     */
    public static Date getLastMonthEnd(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH,1);
        calendar.add(Calendar.DAY_OF_MONTH,-1);
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        calendar.set(Calendar.MILLISECOND,999);
        return calendar.getTime();
    }

    public static void main(String[] args) {
        /*List<String> dateStr = new ArrayList<>();
        for (int i=7;i>=1;i--){
            dateStr.add(getPastDate(i,new Date()));
        }
        System.out.println(dateStr);*/
        System.out.println(formatDateTime(getLastMonthStart()));
        System.out.println(formatDateTime(getLastMonthEnd()));
    }

}
